home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume20 / rc / part01 next >
Encoding:
Text File  |  1991-05-22  |  50.8 KB  |  2,260 lines

  1. Newsgroups: comp.sources.misc
  2. From: Byron Rakitzis <byron@archone.tamu.edu>
  3. Subject:  v20i010:  rc - A Plan 9 shell reimplementation, Part01/04
  4. Message-ID: <1991May22.154142.3038@sparky.IMD.Sterling.COM>
  5. Date: Wed, 22 May 1991 15:41:42 GMT
  6. Approved: kent@sparky.imd.sterling.com
  7. X-Md4-Signature: b408abcee26289e688696dd726246581
  8.  
  9. Submitted-by: Byron Rakitzis <byron@archone.tamu.edu>
  10. Posting-number: Volume 20, Issue 10
  11. Archive-name: rc/part01
  12.  
  13. rc is a command interpreter and programming language similar
  14. to  sh(1).  It is based on the AT&T plan 9 shell of the same
  15. name.  The shell offers a C-like syntax (much more  so  than
  16. the  C  shell),  and  a  powerful mechanism for manipulating
  17. variables.  It is  reasonably  small  and  reasonably  fast,
  18. especially when compared to contemporary shells.  Its use is
  19. intended to be interactive, but the  language  lends  itself
  20. well to scripts.
  21.  
  22. This shell was written by me, Byron Rakitzis, but kudos go to Paul
  23. Haahr for letting me know what a shell should do and for contributing
  24. certain bits and pieces to rc (notably the limits code, most of which.c
  25. and the backquote redirection code), and to Hugh Redelmeier for running
  26. rc through his fussy ANSI compiler and thereby provoking interesting
  27. discussions about portability, and also for providing many valuable
  28. suggestions for improving rc's code in general. Finally, many thanks
  29. go to David Sanderson, for reworking the man page to format well with
  30. troff, and for providing many suggestions both for rc and its man page.
  31.  
  32. Of course, without Tom Duff's design of the original rc, I could not
  33. have written this shell (though I probably would have written *a*
  34. shell). Almost of all of the features, with minor exceptions, have been
  35. implemented as described in the Unix v10 manuals. Hats off to td for
  36. designing a C-like, minimal but very useful shell.
  37.  
  38. Byron Rakitzis
  39. --------------
  40. #! /bin/sh
  41. # This is a shell archive.  Remove anything before this line, then feed it
  42. # into a shell via "sh file" or similar.  To overwrite existing files,
  43. # type "sh file -c".
  44. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  45. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  46. # Contents:  README builtins.c hash.h rc.1
  47. # Wrapped by kent@sparky on Wed May 22 01:21:49 1991
  48. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  49. echo If this archive is complete, you will see the following message:
  50. echo '          "shar: End of archive 1 (of 4)."'
  51. if test -f 'README' -a "${1}" != "-c" ; then 
  52.   echo shar: Will not clobber existing file \"'README'\"
  53. else
  54.   echo shar: Extracting \"'README'\" \(3564 characters\)
  55.   sed "s/^X//" >'README' <<'END_OF_FILE'
  56. XThis is release 1.0 of rc.
  57. X
  58. XRead COPYRIGHT for copying information. All files are
  59. X
  60. XCopyright 1991, Byron Rakitzis.
  61. X
  62. X------ Compiling rc:
  63. X
  64. XTo compile rc, you need an ANSI compiler like gcc. Some compilers which
  65. Xgrok prototypes can also compile rc. In particular, I have successfully
  66. Xcompiled rc using "cc" on the sgi running IRIX-3.3.1 (version 3.2 has
  67. Xan older compiler---rc won't compile under that OS). I avoid using
  68. Xstandard header files as much as possible.  In most cases, this is a
  69. Xwin, but you should pay attention to stddef.h and to rc.h to make
  70. Xsure the values there are suitable for your system.
  71. X
  72. XNote: if you have an IBM PC-RT, you *can* compile rc with IBM's
  73. Xcompiler but you have to tweak the sources a little. I decided not to
  74. Xsupport the RT because /usr/include does not have a stdarg.h, but
  75. Xdesperate RT users can contact me for porting info.
  76. X
  77. XIf you are on a pure system V machine, you may have define certain
  78. Xmacros to omit certain pieces of code. In particular, defining the
  79. XNOLIMITS macro will #ifdef out the Berkeley limits code.
  80. XAlso, the NOJOB macro if defined will omit certain calls to signal()
  81. Xused to make rc work on Berkeley systems that assume csh. (note that rc
  82. Xdoes *not* support csh-style job control in either case)
  83. XSimilarly, the NONMPIPES macro omits support for <{} redirection on
  84. Xsystems which do not support named pipes.
  85. X
  86. XFinally, on older systems without "<dirent.h>", the macro
  87. X"NODIRENT" must be defined. This substitutes "<sys/dir.h>" for
  88. X"<dirent.h>" and uses struct direct instead of struct dirent.
  89. X
  90. X------ Bugs:
  91. X
  92. XSend bug reports to byron@archone.tamu.edu. If a core dump is
  93. Xgenerated, sending me a backtrace will help me out a great deal. You
  94. Xcan get a backtrace like this:
  95. X
  96. X    ; gdb rc core
  97. X    (gdb) where
  98. X    <<<BACKTRACE INFO>>>
  99. X    (gdb)
  100. X
  101. XAlso, always report the machine, compiler and os used to make rc.  It's
  102. Xpossible I may have access to a machine of that type, in which case it
  103. Xbecomes much easier for me to track the bug down.
  104. X
  105. X------ Man page:
  106. XThe man page works with nroff on my Sun, but I had to use groff in
  107. Xorder to get the sample code to be typeset in typewriter type. I
  108. Xam assuming that ditroff will also format rc.1 correctly for a
  109. Xprinter. If anyone can tell me how to get BSD troff to do this,
  110. XI would be grateful.
  111. X
  112. X------ Feeping Creaturism:
  113. X
  114. XSee the end of the man page, under "INCOMPATIBILITIES" for (known?)
  115. Xdifferences from the "real" rc. Most of these changes were necessary
  116. Xto get rc to work in a reasonable fashion on a real UNIX system; a
  117. Xfew were changes motivated by concern about some inadequacies in
  118. Xthe original design.
  119. X
  120. X------ Credits:
  121. X
  122. XThis shell was written by me, Byron Rakitzis, but kudos go to Paul
  123. XHaahr for letting me know what a shell should do and for contributing
  124. Xcertain bits and pieces to rc (notably the limits code, most of which.c
  125. Xand the backquote redirection code), and to Hugh Redelmeier for running
  126. Xrc through his fussy ANSI compiler and thereby provoking interesting
  127. Xdiscussions about portability, and also for providing many valuable
  128. Xsuggestions for improving rc's code in general. Finally, many thanks
  129. Xgo to David Sanderson, for reworking the man page to format well with
  130. Xtroff, and for providing many suggestions both for rc and its man page.
  131. X
  132. XOf course, without Tom Duff's design of the original rc, I could not
  133. Xhave written this shell (though I probably would have written *a*
  134. Xshell). Almost of all of the features, with minor exceptions, have been
  135. Ximplemented as described in the Unix v10 manuals. Hats off to td for
  136. Xdesigning a C-like, minimal but very useful shell.
  137. END_OF_FILE
  138.   if test 3564 -ne `wc -c <'README'`; then
  139.     echo shar: \"'README'\" unpacked with wrong size!
  140.   fi
  141.   # end of 'README'
  142. fi
  143. if test -f 'builtins.c' -a "${1}" != "-c" ; then 
  144.   echo shar: Will not clobber existing file \"'builtins.c'\"
  145. else
  146.   echo shar: Extracting \"'builtins.c'\" \(10271 characters\)
  147.   sed "s/^X//" >'builtins.c' <<'END_OF_FILE'
  148. X/* builtins.c: the collection of rc's builtin commands */
  149. X
  150. X#include <setjmp.h>
  151. X#ifndef NOLIMITS
  152. X#include <sys/time.h>
  153. X#include <sys/resource.h>
  154. X#endif
  155. X#include "rc.h"
  156. X#include "utils.h"
  157. X#include "walk.h"
  158. X#include "input.h"
  159. X#include "builtins.h"
  160. X#include "hash.h"
  161. X#include "nalloc.h"
  162. X#include "status.h"
  163. X#include "footobar.h"
  164. X#include "lex.h"
  165. X#include "open.h"
  166. X#include "except.h"
  167. X#include "redir.h"
  168. X#include "glom.h"
  169. X#include "tree.h"
  170. X
  171. Xextern int umask(int);
  172. X
  173. Xstatic void b_break(char **), b_builtin(char **), b_cd(char **),
  174. X    b_echo(char **), b_eval(char **), b_exit(char **), b_limit(char **),
  175. X    b_return(char **), b_shift(char **), b_umask(char **), b_wait(char **),
  176. X    b_whatis(char **);
  177. X
  178. Xstatic builtin_t *const builtins[] = {
  179. X    b_break, b_builtin, b_cd, b_echo, b_eval, b_exec, b_exit,
  180. X    b_limit, b_return, b_shift, b_umask, b_wait, b_whatis, b_dot
  181. X};
  182. X
  183. Xstatic char *const builtins_str[] = {
  184. X    "break", "builtin", "cd", "echo", "eval", "exec", "exit",
  185. X    "limit", "return", "shift", "umask", "wait", "whatis", "."
  186. X};
  187. X
  188. Xbuiltin_t *isbuiltin(char *s) {
  189. X    int i;
  190. X
  191. X    for (i = 0; i < arraysize(builtins_str); i++)
  192. X        if (streq(builtins_str[i], s))
  193. X            return builtins[i];
  194. X    return NULL;
  195. X}
  196. X
  197. X/* funcall() is the wrapper used to invoke shell functions. pushes $*, and "return" returns here. */
  198. X
  199. Xvoid funcall(char **av) {
  200. X    jmp_buf j;
  201. X    Estack e1, e2;
  202. X
  203. X    if (setjmp(j))
  204. X        return;
  205. X
  206. X    starassign(*av, av+1, TRUE);
  207. X    except(RETURN, j, &e1);
  208. X    except(STAR, NULL, &e2);
  209. X    walk(treecpy(fnlookup(*av),nalloc), TRUE);
  210. X    varrm("*", TRUE);
  211. X    unexcept(); /* STAR */
  212. X    unexcept(); /* RETURN */
  213. X}
  214. X
  215. X/* a dummy command. not really used to exec commands (exec() does this simply by not forking) */
  216. X
  217. Xvoid b_exec(char **av) {
  218. X    if (av[1] == NULL) /* on a null exec, perform redirections */
  219. X        doredirs();
  220. X    return;
  221. X}
  222. X
  223. X/* echo -n omits a newline. echo -- -n echos '-n' */
  224. X
  225. Xstatic void b_echo(char **av) {
  226. X    SIZE_T i;
  227. X    char *format = "%a\n";
  228. X
  229. X    if (*++av != NULL) {
  230. X        if (streq(*av, "-n")) {
  231. X            format = "%a";
  232. X            av++;
  233. X        } else if (streq(*av, "--")) {
  234. X            av++;
  235. X        }
  236. X    }
  237. X    
  238. X    i = strarraylen(av) + 1; /* one for the null terminator */
  239. X
  240. X    if (i < FPRINT_SIZE)
  241. X        fprint(1, format, av);
  242. X    else
  243. X        writeall(1, sprint(nalloc(i), format, av), i-1);
  244. X    set(TRUE);
  245. X}
  246. X
  247. X/* cd. traverse $cdpath if the directory given is not an absolute pathname */
  248. X
  249. Xstatic void b_cd(char **av) {
  250. X    List *s, nil;
  251. X    char *path = NULL;
  252. X    SIZE_T t, pathlen = 0;
  253. X
  254. X    if (*++av == NULL) {
  255. X        s = varlookup("home");
  256. X        *av = (s == NULL) ? "/" : s->w;
  257. X    }
  258. X    if (isabsolute(*av)) { /* absolute pathname? */
  259. X        if (chdir(*av) < 0) {
  260. X            set(FALSE);
  261. X            uerror(*av);
  262. X        } else
  263. X            set(TRUE);
  264. X    } else {
  265. X        s = varlookup("cdpath");
  266. X        if (s == NULL) {
  267. X            s = &nil;
  268. X            nil.w = "";
  269. X            nil.n = NULL;
  270. X        }
  271. X        do {
  272. X            if (s != &nil && *s->w != '\0') {
  273. X                t = strlen(*av) + strlen(s->w) + 2;
  274. X                if (t > pathlen)
  275. X                    path = nalloc(pathlen = t);
  276. X                strcpy(path, s->w);
  277. X                strcat(path, "/");
  278. X                strcat(path, *av);
  279. X            } else {
  280. X                pathlen = 0;
  281. X                path = *av;
  282. X            }
  283. X            if (chdir(path) >= 0) {
  284. X                set(TRUE);
  285. X                if (interactive && *s->w != '\0' && !streq(s->w,"."))
  286. X                    fprint(1,"%s\n",path);
  287. X                return;
  288. X            }
  289. X            s = s->n;
  290. X        } while (s != NULL);
  291. X        fprint(2,"couldn't cd to %s\n", *av);
  292. X        set(FALSE);
  293. X    }
  294. X}
  295. X
  296. Xstatic void b_umask(char **av) {
  297. X    int i;
  298. X
  299. X    if (*++av == NULL) {
  300. X        set(TRUE);
  301. X        i = umask(0);
  302. X        umask(i);
  303. X        fprint(2,"0%o\n",i);
  304. X    } else {
  305. X        i = o2u(*av);
  306. X        if ((unsigned int) i > 0777) {
  307. X            set(FALSE);
  308. X            fprint(2,"bad umask\n");
  309. X        } else {
  310. X            set(TRUE);
  311. X            umask(i);
  312. X        }
  313. X    }
  314. X}
  315. X
  316. Xstatic void b_exit(char **av) {
  317. X    int s;
  318. X
  319. X    if (av[1] == NULL)
  320. X        rc_exit(getstatus());
  321. X    if ((s = a2u(av[1])) >= 0)
  322. X        rc_exit(s);
  323. X    fprint(2,"%s is a bad number\n", av[1]);
  324. X    rc_exit(1);
  325. X}
  326. X
  327. X/* raise a "return" exception, i.e., return from a function. if an integer argument is present, set $status to it */
  328. X
  329. Xstatic void b_return(char **av) {
  330. X    int s;
  331. X
  332. X    if (av[1] != NULL) {
  333. X        s = a2u(av[1]);
  334. X        if (s < 0) {
  335. X            fprint(2,"%s is a bad number\n", av[1]);
  336. X            set(FALSE);
  337. X        } else {
  338. X            setstatus(s << 8);
  339. X        }
  340. X    }
  341. X    rc_raise(RETURN);
  342. X}
  343. X
  344. X/* raise a "break" exception for breaking out of for and while loops */
  345. X
  346. Xstatic void b_break(char **av) {
  347. X    rc_raise(BREAK);
  348. X}
  349. X
  350. X/* shift $* n places (default 1) */
  351. X
  352. Xstatic void b_shift(char **av) {
  353. X    int shift;
  354. X    List *s, *dollarzero;
  355. X
  356. X    shift = (av[1] == NULL ? 1 : a2u(av[1]));
  357. X
  358. X    if (shift < 0) {
  359. X        fprint(2,"%s is a bad number\n", av[1]);
  360. X        set(FALSE);
  361. X        return;
  362. X    }
  363. X
  364. X    s = varlookup("*")->n;
  365. X    dollarzero = varlookup("0");
  366. X
  367. X    while(s != NULL && shift != 0) {
  368. X        s = s->n;
  369. X        --shift;
  370. X    }
  371. X
  372. X    varassign("*", append(dollarzero, s), FALSE);
  373. X    set(TRUE);
  374. X}
  375. X
  376. X/* works by advancing argv by one, really. This means that if builtin is defined as a function you are hosed */
  377. X
  378. Xstatic void b_builtin(char **av) {
  379. X    builtin_t *b;
  380. X
  381. X    if (av[1] == NULL) {
  382. X        set(FALSE);
  383. X        fprint(2,"no arguments to 'builtin'\n");
  384. X        return;
  385. X    }
  386. X    if ((b = isbuiltin(av[1])) == NULL) {
  387. X        set(FALSE);
  388. X        fprint(2,"no such builtin\n");
  389. X    } else {
  390. X        set(TRUE);
  391. X        b(++av);
  392. X    }
  393. X}
  394. X
  395. X/* wait for a given process, or all outstanding processes */
  396. X
  397. Xstatic void b_wait(char **av) {
  398. X    int stat, pid;
  399. X
  400. X    if (av[1] == NULL) {
  401. X        pid = wait(&stat);
  402. X        if (pid < 0)
  403. X            uerror("wait");
  404. X        while(wait(&stat) >= 0)
  405. X            ;
  406. X        return;
  407. X    } else {
  408. X        pid = a2u(av[1]);
  409. X        if (pid < 0) {
  410. X            set(FALSE);
  411. X            fprint(2,"%s is a bad number\n", av[1]);
  412. X            return;
  413. X        }
  414. X        while (pid != wait(&stat))
  415. X            if (pid < 0)
  416. X                uerror("wait");
  417. X    }
  418. X    if (pid < 0)
  419. X        set(FALSE);
  420. X    else
  421. X        setstatus(stat);
  422. X}
  423. X
  424. X/*
  425. X   whatis without arguments prints all variables and functions. Otherwise, check to see if a name
  426. X   is defined as a variable, function or pathname.
  427. X*/
  428. X
  429. Xstatic void b_whatis(char **av) {
  430. X    enum bool f,found;
  431. X    int i,j;
  432. X    List *s,*t;
  433. X    Node *n;
  434. X    char *e;
  435. X
  436. X    if (av[1] == NULL) {
  437. X        whatare_all_vars();
  438. X        set(TRUE);
  439. X        return;
  440. X    }
  441. X    found = TRUE;
  442. X    for (i = 1; av[i] != NULL; i++) {
  443. X        f = FALSE;
  444. X        if ((s = varlookup(av[i])) != NULL) {
  445. X            f = TRUE;
  446. X            fprint(1,"%s=%s", av[i], (s->n == NULL ? "" : "("));
  447. X            for (t = s; t->n != NULL; t = t->n)
  448. X                fprint(1,"%s ",strprint(t->w, FALSE, TRUE));
  449. X            fprint(1,"%s%s\n",strprint(t->w, FALSE, TRUE), (s->n == NULL ? "" : ")"));
  450. X        }
  451. X        if ((n = fnlookup(av[i])) != NULL) {
  452. X            f = TRUE;
  453. X            fprint(1,"fn %s {%s}\n",av[i],ptree(n));
  454. X        } else if (isbuiltin(av[i]) != NULL) {
  455. X            f = TRUE;
  456. X            for (j = 0; j < arraysize(builtins_str); j++)
  457. X                if (streq(av[i], builtins_str[j]))
  458. X                    break;
  459. X            fprint(1,"builtin %s\n",builtins_str[j]);
  460. X        } else if ((e = which(av[i])) != NULL) {
  461. X            f = TRUE;
  462. X            fprint(1,"%s\n",e);
  463. X        }
  464. X        if (!f) {
  465. X            found = FALSE;
  466. X            fprint(2,"%s not found\n", av[i]);
  467. X        }
  468. X    }
  469. X
  470. X    set(found);
  471. X}
  472. X
  473. X/* push a string to be eval'ed onto the input stack. evaluate it */
  474. X
  475. Xstatic void b_eval(char **av) {
  476. X    boolean i = interactive;
  477. X
  478. X    if (av[1] == NULL)
  479. X        return;
  480. X
  481. X    interactive = FALSE;
  482. X    pushinput(STRING, av + 1);
  483. X    doit(TRUE);
  484. X    interactive = i;
  485. X}
  486. X
  487. X/*
  488. X   push a file to be interpreted onto the input stack. with "-i" treat this as an interactive
  489. X   input source.
  490. X*/
  491. X
  492. Xvoid b_dot(char **av) {
  493. X    int fd;
  494. X    boolean old_i = interactive, i = FALSE;
  495. X    Estack e;
  496. X
  497. X    av++;
  498. X
  499. X    if (*av == NULL || **av == '\0')
  500. X        return;
  501. X
  502. X    if (streq(*av,"-i")) {
  503. X        av++;
  504. X        i = TRUE;
  505. X    }
  506. X
  507. X    if (dasheye) { /* rc -i file has to do the right thing. reset the dasheye state to FALSE, though. */
  508. X        dasheye = FALSE;
  509. X        i = TRUE;
  510. X    }
  511. X
  512. X    fd = rc_open(*av, FROM);
  513. X
  514. X    if (fd < 0) {
  515. X        if (rcrc) /* on rc -l, don't flag nonexistence of .rcrc */
  516. X            rcrc = FALSE;
  517. X        else
  518. X            uerror(*av);
  519. X        set(FALSE);
  520. X        return;
  521. X    }
  522. X    rcrc = FALSE;
  523. X
  524. X    starassign(*av, av+1, TRUE);
  525. X    pushinput(FD, fd);
  526. X    interactive = i;
  527. X    except(STAR, NULL, &e);
  528. X    doit(TRUE);
  529. X    varrm("*", TRUE);
  530. X    unexcept(); /* STAR */
  531. X    interactive = old_i;
  532. X}
  533. X
  534. X/* Berkeley limit support was cleaned up by Paul Haahr. */
  535. X
  536. X#ifdef NOLIMITS
  537. Xstatic void b_limit(char **av) {
  538. X    fprint(2,"rc was compiled without berkeley limits\n");
  539. X    set(FALSE);
  540. X}
  541. X#else
  542. X
  543. Xtypedef struct Suffix Suffix;
  544. Xstruct Suffix {
  545. X    const Suffix *next;
  546. X    long amount;
  547. X    char *name;
  548. X};
  549. X
  550. Xstatic const Suffix
  551. X    kbsuf = { NULL, 1024, "k" },
  552. X    mbsuf = { &kbsuf, 1024*1024, "m" },
  553. X    gbsuf = { &mbsuf, 1024*1024*1024, "g" },
  554. X    stsuf = { NULL, 1, "s" },
  555. X    mtsuf = { &stsuf, 60, "m" },
  556. X    htsuf = { &mtsuf, 60*60, "h" };
  557. X#define    SIZESUF &gbsuf
  558. X#define    TIMESUF &htsuf
  559. X
  560. Xtypedef struct {
  561. X    char *name;
  562. X    int flag;
  563. X    const Suffix *suffix;
  564. X} Limit;
  565. Xstatic const Limit limits[] = {
  566. X    { "cputime",        RLIMIT_CPU,    TIMESUF },
  567. X    { "filesize",        RLIMIT_FSIZE,    SIZESUF },
  568. X    { "datasize",        RLIMIT_DATA,    SIZESUF },
  569. X    { "stacksize",        RLIMIT_STACK,    SIZESUF },
  570. X    { "coredumpsize",    RLIMIT_CORE,    SIZESUF },
  571. X    { "memoryuse",        RLIMIT_RSS,    SIZESUF },
  572. X    { NULL, 0, NULL }
  573. X};
  574. X
  575. Xextern int getrlimit(int, struct rlimit *);
  576. Xextern int setrlimit(int, struct rlimit *);
  577. X
  578. Xstatic void printlimit(const Limit *limit, boolean hard) {
  579. X    struct rlimit rlim;
  580. X    long lim;
  581. X    getrlimit(limit->flag, &rlim);
  582. X    if (hard)
  583. X        lim = rlim.rlim_max;
  584. X    else
  585. X        lim = rlim.rlim_cur;
  586. X    if (lim == RLIM_INFINITY)
  587. X        fprint(1, "%s \tunlimited\n", limit->name);
  588. X    else {
  589. X        const Suffix *suf;
  590. X        for (suf = limit->suffix; suf != NULL; suf = suf->next)
  591. X            if (lim % suf->amount == 0) {
  592. X                lim /= suf->amount;
  593. X                break;
  594. X            }
  595. X        fprint(1, "%s \t%d%s\n", limit->name, lim, suf == NULL ? "" : suf->name);
  596. X    }
  597. X}
  598. X
  599. Xstatic long parselimit(const Limit *limit, char *s) {
  600. X    int len = strlen(s);
  601. X    long lim = 1;
  602. X    const Suffix *suf = limit->suffix;
  603. X    if (streq(s, "unlimited"))
  604. X        return RLIM_INFINITY;
  605. X    if (suf == TIMESUF && strchr(s, ':') != NULL) {
  606. X        char *t = strchr(s, ':');
  607. X        *t++ = '\0';
  608. X        lim = 60 * a2u(s) + a2u(t);
  609. X    } else {
  610. X        for (; suf != NULL; suf = suf->next)
  611. X            if (streq(suf->name, s + len - strlen(suf->name))) {
  612. X                s[len - strlen(suf->name)] = '\0';
  613. X                lim *= suf->amount;
  614. X                break;
  615. X            }
  616. X        lim *= a2u(s);
  617. X    }
  618. X    if (lim < 0)
  619. X        rc_error("bad limit");
  620. X    return lim;
  621. X}
  622. X
  623. Xstatic void b_limit(char **av) {
  624. X    const Limit *lp = limits;
  625. X    boolean hard = FALSE;
  626. X
  627. X    if (*++av != NULL && streq(*av, "-h")) {
  628. X        av++;
  629. X        hard = TRUE;
  630. X    }
  631. X
  632. X    if (*av == NULL) {
  633. X        for (; lp->name != NULL; lp++)
  634. X            printlimit(lp, hard);
  635. X        return;
  636. X    }
  637. X
  638. X    for (;; lp++) {
  639. X        if (lp->name == NULL)
  640. X            rc_error("no such limit");
  641. X        if (streq(*av, lp->name))
  642. X            break;
  643. X    }
  644. X
  645. X    if (*++av == NULL)
  646. X        printlimit(lp, hard);
  647. X    else {
  648. X        struct rlimit rlim;
  649. X        getrlimit(lp->flag, &rlim);
  650. X        if (hard)
  651. X            rlim.rlim_max = parselimit(lp, *av);
  652. X        else
  653. X            rlim.rlim_cur = parselimit(lp, *av);
  654. X        if (setrlimit(lp->flag, &rlim) == -1)
  655. X            uerror("setrlimit");
  656. X    }
  657. X}
  658. X#endif
  659. END_OF_FILE
  660.   if test 10271 -ne `wc -c <'builtins.c'`; then
  661.     echo shar: \"'builtins.c'\" unpacked with wrong size!
  662.   fi
  663.   # end of 'builtins.c'
  664. fi
  665. if test -f 'hash.h' -a "${1}" != "-c" ; then 
  666.   echo shar: Will not clobber existing file \"'hash.h'\"
  667. else
  668.   echo shar: Extracting \"'hash.h'\" \(1175 characters\)
  669.   sed "s/^X//" >'hash.h' <<'END_OF_FILE'
  670. Xtypedef struct Function {
  671. X    Node *def;
  672. X    char *extdef;
  673. X} Function;
  674. X
  675. Xtypedef struct Variable {
  676. X    List *def;
  677. X    char *extdef;
  678. X    struct Variable *n;
  679. X} Variable;
  680. X
  681. Xtypedef struct Htab {
  682. X    char *name;
  683. X    void *p;
  684. X} Htab;
  685. X
  686. Xextern Htab *fp, *vp;
  687. X
  688. X#define lookup_fn(s) ((Function *) lookup(s,fp))
  689. X#define lookup_var(s) ((Variable *) lookup(s,vp))
  690. X
  691. Xextern void *lookup(char *, Htab *);
  692. Xextern Function *get_fn_place(char *);
  693. Xextern List *varlookup(char *);
  694. Xextern Node *fnlookup(char *);
  695. Xextern Variable *get_var_place(char *, boolean);
  696. Xextern boolean varassign_string(char *);
  697. Xextern char **makeenv(void);
  698. Xextern char *fnlookup_string(char *);
  699. Xextern char *varlookup_string(char *);
  700. Xextern void alias(char *, List *, boolean);
  701. Xextern void starassign(char *, char **, boolean);
  702. Xextern void delete_fn(char *);
  703. Xextern void delete_var(char *, boolean);
  704. Xextern void fnassign(char *, Node *);
  705. Xextern void fnassign_string(char *);
  706. Xextern void fnrm(char *);
  707. Xextern void initenv(char **);
  708. Xextern void inithash(void);
  709. Xextern void setsigdefaults(void);
  710. Xextern void inithandler(void);
  711. Xextern void varassign(char *, List *, boolean);
  712. Xextern void varrm(char *, boolean);
  713. Xextern void whatare_all_vars(void);
  714. END_OF_FILE
  715.   if test 1175 -ne `wc -c <'hash.h'`; then
  716.     echo shar: \"'hash.h'\" unpacked with wrong size!
  717.   fi
  718.   # end of 'hash.h'
  719. fi
  720. if test -f 'rc.1' -a "${1}" != "-c" ; then 
  721.   echo shar: Will not clobber existing file \"'rc.1'\"
  722. else
  723.   echo shar: Extracting \"'rc.1'\" \(30362 characters\)
  724.   sed "s/^X//" >'rc.1' <<'END_OF_FILE'
  725. X.\" rc.1
  726. X.\" Dd    distance to space vertically before a "display"
  727. X.\" These are what n/troff use for interparagraph distance
  728. X.if t .nr Dd .4v
  729. X.if n .nr Dd 1v
  730. X.\" Ds    begin a display
  731. X.de Ds
  732. X.RS \\$1
  733. X.sp \\n(Ddu
  734. X.nf
  735. X..
  736. X.\" De    end a display (no trailing vertical spacing)
  737. X.de De
  738. X.fi
  739. X.RE
  740. X..
  741. X.ds Cf C
  742. X.de Cw
  743. X.lg 0
  744. X\%\&\\$3\f\\*(Cf\\$1\f1\&\\$2
  745. X.lg
  746. X..
  747. X.TH RC 1 "28 April 1991"
  748. X.SH NAME
  749. Xrc \- shell
  750. X.SH SYNOPSIS
  751. X.B rc
  752. X[
  753. X.B \-eixvld
  754. X] [
  755. X.B -c
  756. X.I command
  757. X] [
  758. X.I arguments
  759. X]
  760. X.SH DESCRIPTION
  761. X.I rc
  762. Xis a command interpreter and programming language similar to
  763. X.IR sh (1).
  764. XIt is based on the AT&T plan 9 shell of the same name.
  765. XThe shell offers a C-like syntax (much more so than the C shell),
  766. Xand a powerful mechanism for manipulating variables.
  767. XIt is reasonably small and reasonably fast,
  768. Xespecially when compared to contemporary shells.
  769. XIts use is intended to be interactive,
  770. Xbut the language lends itself well to scripts.
  771. X.SH OPTIONS
  772. X.TP
  773. X.B \-e
  774. XIf the
  775. X.Cw \-e
  776. Xoption is present, then
  777. X.I rc
  778. Xwill exit if the exit status of a command is false (nonzero).
  779. X.I rc
  780. Xwill not exit, however, if a conditional fails, e.g., an
  781. X.Cw if()
  782. Xcommand.
  783. X.TP
  784. X.B \-i
  785. XIf the
  786. X.Cw \-i
  787. Xoption is present or if the input to
  788. X.I rc
  789. Xis from a terminal (as determined by
  790. X.IR isatty (3))
  791. Xthen
  792. X.I rc
  793. Xwill be in
  794. X.I interactive
  795. Xmode.
  796. XThat is, a prompt (from
  797. X.Cw $prompt(1)
  798. Xwill be printed before an
  799. Xinput line is taken, and
  800. X.I rc
  801. Xwill ignore the signals
  802. X.Cw SIGINT
  803. Xand
  804. X.Cw SIGQUIT .
  805. X.TP
  806. X.B \-x
  807. XThis option will make
  808. X.I rc
  809. Xprint every command on standard error before it is executed.
  810. XIt can be useful for debugging
  811. X.I rc
  812. Xscripts.
  813. X.TP
  814. X.B \-v
  815. XThis option will echo input to
  816. X.I rc
  817. Xon standard error as it is read.
  818. X.TP
  819. X.B \-l
  820. XIf the
  821. X.Cw \-l
  822. Xoption is present, or if
  823. X.IR rc 's
  824. X.Cw argv[0][0]
  825. Xis a dash
  826. X.Cw - ), (
  827. Xthen
  828. X.I rc
  829. Xwill behave as a login shell.
  830. XThat is, it will try to run commands present in
  831. X.Cw $home/.rcrc ,
  832. Xif this file exists, before reading any other input.
  833. X.TP
  834. X.B \-d
  835. XThis flag causes
  836. X.I rc
  837. Xnot to trap
  838. X.Cw SIGQUIT ,
  839. Xand thus
  840. X.I rc
  841. Xwill dump core when it receives this signal.
  842. XThis option is only useful for debugging
  843. X.IR rc .
  844. X.TP
  845. X.B \-c
  846. XIf
  847. X.Cw \-c
  848. Xis present, commands are executed from the immediately following
  849. Xargument.
  850. XAny further arguments to
  851. X.I rc
  852. Xare placed in
  853. X.Cw $* .
  854. X.PP
  855. X.SH COMMANDS
  856. XA simple command is a sequence of words, separated by white space
  857. X(space and tab) characters that ends with a newline, semicolon
  858. X.Cw ; ), (
  859. Xor ampersand
  860. X.Cw & ). (
  861. XThe first word of a command is the name of that command.
  862. XIf the name begins with 
  863. X.Cw / ,
  864. X.Cw ./ ,
  865. Xor
  866. X.Cw ../ ,
  867. Xthen the name is used as an absolute path
  868. Xname referring to an executable file.
  869. XOtherwise, the name of the command is looked up in a table
  870. Xof shell functions, builtin commands,
  871. Xor as a file in the directories named by
  872. X.Cw $path .
  873. X.SS "Background Tasks"
  874. XA command ending with a
  875. X.Cw &
  876. Xis run in the background; that is,
  877. Xthe shell returns immediately rather than waiting for the command to
  878. Xcomplete.
  879. XBackground commands have
  880. X.I /dev/null
  881. Xconnected to their standard input unless an explicit redirection for
  882. Xstandard input is used.
  883. X.SS "Subshells"
  884. XA command prefixed with an at-sign
  885. X.Cw @ ) (
  886. Xis executed in a subshell.
  887. XThis insulates the parent shell from the effects
  888. Xof a
  889. X.B cd
  890. Xor a variable assignment.
  891. XFor example:
  892. X.Ds
  893. X.Cw "@ {cd ..; make}
  894. X.De
  895. X.PP
  896. Xwill run
  897. X.IR make (1)
  898. Xin the parent directory
  899. X.Cw .. ), (
  900. Xbut leaves the shell running in the current directory.
  901. X.SS "Line continuation"
  902. XA long logical line may be continued over several physical lines by
  903. Xterminating each line (except the last) with a backslash
  904. X.Cw \e ). (
  905. XThe backslash-newline sequence is treated as a space.
  906. XA backslash is not otherwise special to
  907. X.IR rc .
  908. X.SS Quoting
  909. X.IR rc
  910. Xinterprets several characters specially; special characters
  911. Xautomatically terminate words.
  912. XThe following characters are special:
  913. X.Ds
  914. X.Cw "# ; & | ^ $ = ` ' { } ( ) < >\fR
  915. X.De
  916. X.PP
  917. XThe single quote
  918. X.Cw ' ) (
  919. Xprevents special treatment of any character other than itself.
  920. XAll characters, including control characters, newlines,
  921. Xand backslashes between two quote characters are treated as an
  922. Xuninterpreted string.
  923. XA quote character itself may be quoted by placing two quotes in a row.
  924. XThe minimal sequence needed to enter the quote character is
  925. X.Cw '''' .
  926. XThe empty string is represented by
  927. X.Cw '' .
  928. XThus:
  929. X.Ds
  930. X.Cw "echo 'What''s the plan, Stan?'
  931. X.De
  932. X.PP
  933. Xprints out
  934. X.Ds
  935. X.Cw "What's the plan, Stan?
  936. X.De
  937. X.SS Grouping
  938. XZero or more commands may be grouped within braces
  939. X.Cw { ' (`
  940. Xand
  941. X.Cw } '), `
  942. Xand are then treated as one command.
  943. XBraces do not otherwise define scope;
  944. Xthey are used only for command grouping.
  945. XIn particular, be wary of the command:
  946. X.Ds
  947. X.Cw "for (i) {
  948. X.Cw "    command
  949. X.Cw "} | command
  950. X.De
  951. X.PP
  952. XSince pipe binds tighter than
  953. X.BR for ,
  954. Xthis command does not perform what the user expects it to.
  955. XInstead, enclose the whole
  956. X.B for
  957. Xstatement in braces:
  958. X.Ds
  959. X.Cw "{for (i) command} | command
  960. X.De
  961. X.PP
  962. XFortunately,
  963. X.IR rc 's
  964. Xgrammar is simple enough that a (confident) user can
  965. Xunderstand it by examining the skeletal yacc grammar
  966. Xat the end of this man page (see the section entitled
  967. XGRAMMAR).
  968. X.SS "Input and output"
  969. X.PP
  970. XThe standard output may be redirected to a file with
  971. X.Ds
  972. X.Cw "command > file"
  973. X.De
  974. X.PP
  975. Xand the standard input may be taken from a file with
  976. X.Ds
  977. X.Cw "command < file
  978. X.De
  979. X.PP
  980. XFile descriptors other than 0 and 1 may be specified also.
  981. XFor example, to redirect standard error to a file, use:
  982. X.Ds
  983. X.Cw "command >[2] file
  984. X.De
  985. X.PP
  986. XIn order to duplicate a file descriptor, use
  987. X\f\*(Cf>[\fIn\f\*(Cf=\fIm\f\*(Cf]\fR.
  988. XThus to redirect both standard output and standard error
  989. Xto the same file, use
  990. X.Ds
  991. X.Cw "command > file >[2=1]
  992. X.De
  993. X.PP
  994. XTo close a file descriptor that may be open, use
  995. X\f\*(Cf>[\fIn\f\*(Cf=]\fR.
  996. XFor example, to
  997. Xclose file-descriptor 7:
  998. X.Ds
  999. X.Cw "command >[7=]
  1000. X.De
  1001. X.PP
  1002. XIn order to place the output of a command at the end of an already
  1003. Xexisting file, use:
  1004. X.Ds
  1005. X.Cw "command >> file
  1006. X.De
  1007. X.PP
  1008. XIf the file does not exist, then it is created.
  1009. X.PP
  1010. X``Here documents'' are supported as in
  1011. X.IR sh (1)
  1012. Xwith the use of
  1013. X.Ds
  1014. X.Cw "command << 'eof-marker'
  1015. X.De
  1016. X.PP
  1017. XIf the end-of-file marker is enclosed in quotes, then no variable substitution
  1018. Xoccurs inside the here document.
  1019. XOtherwise, every variable is
  1020. Xsubstituted by its space-separated-list value (see Flat Lists, below),
  1021. Xand if a
  1022. X.Cw ^
  1023. Xcharacter follows a variable name, it is deleted.
  1024. XThis allows the unambiguous use of variables adjacent to text, as in
  1025. X.Ds
  1026. X.Cw $variable^follow
  1027. X.De
  1028. X.PP
  1029. XAdditionally,
  1030. X.I rc
  1031. Xsupports ``here strings'', which are like here documents, except that input
  1032. Xis taken directly from a string on the command line. Its use is illustrated
  1033. Xhere:
  1034. X.Ds
  1035. X.Cw "cat <<< 'this is a here string' | wc
  1036. X.De
  1037. X.PP
  1038. X(This feature enables
  1039. X.I rc
  1040. Xto export functions using here documents into the environment; the author
  1041. Xdoes not expect users to find this feature useful.)
  1042. X.SS Pipes
  1043. XTwo or more commands may be combined in a pipeline by placing the
  1044. Xvertical bar
  1045. X.Cw | ) (
  1046. Xbetween them.
  1047. XThe standard output (file descriptor 1)
  1048. Xof the command on the left is tied to the standard input (file
  1049. Xdescriptor 0) of the command on the right.
  1050. XThe notation
  1051. X\f\*(Cf|[\fIn\f\*(Cf=\fIm\f\*(Cf]\fR
  1052. Xindicates that file descriptor
  1053. X.I n
  1054. Xof the left process is connected to
  1055. Xfile descriptor
  1056. X.I m
  1057. Xof the right process.
  1058. X\f\*(Cf|[\fIn\f\*(Cf]\fR
  1059. Xis a shorthand for
  1060. X\f\*(Cf|[\fIn\f\*(Cf=0]\fR.
  1061. XAs an example, to pipe the standard error of a command to
  1062. X.IR wc (1),
  1063. Xuse:
  1064. X.Ds
  1065. X.Cw "command |[2] wc
  1066. X.De
  1067. X.SS "Commands as Arguments"
  1068. XSome commands, like
  1069. X.IR cmp (1)
  1070. Xor
  1071. X.IR diff (1),
  1072. Xtake their arguments on the command
  1073. Xline, and do not read input from standard input.
  1074. XIt is convenient
  1075. Xsometimes to build nonlinear pipelines so that a command like cmp can
  1076. Xread the output of two other commands at once.
  1077. X.I rc
  1078. Xdoes it like this:
  1079. X.Ds
  1080. X.Cw "cmp <{command} <{command}
  1081. X.De
  1082. X.PP
  1083. Xcompares the output of the two commands in braces.
  1084. XA note: since this form of
  1085. Xredirection is implemented with named pipes, and since one cannot
  1086. X.IR lseek (2)
  1087. Xon a pipe, commands that use
  1088. X.IR lseek (2)
  1089. Xwill hang.
  1090. XFor example,
  1091. Xmost versions of
  1092. X.IR diff (1)
  1093. Xuse
  1094. X.IR lseek (2)
  1095. Xon their inputs.
  1096. X.SH "CONTROL STRUCTURES"
  1097. XThe following may be used for control flow in
  1098. X.IR rc :
  1099. X.SS "If-else Statements"
  1100. X.PD 0
  1101. X.sp
  1102. X\fBif (\fItest\fB) {
  1103. X.br
  1104. X.B "    " \fIcmd\fB
  1105. X.br
  1106. X.TP
  1107. X.B } else \fIcmd\fB
  1108. XThe
  1109. X.I test
  1110. Xis executed, and if its return status is zero, the first
  1111. Xcommand is executed, otherwise the second is.
  1112. XBraces are not mandatory around the commands.
  1113. XHowever, an else statement is valid only if it
  1114. Xfollows a close-brace on the same line.
  1115. XOtherwise, the if is taken to be a simple-if:
  1116. X.Ds
  1117. X.Cw "if (test)
  1118. X.Cw "    command
  1119. X.De
  1120. X.PD
  1121. X.SS "While and For Loops"
  1122. X.TP
  1123. X.B while (\fItest\fB) \fIcmd\fB
  1124. X.I rc
  1125. Xexecutes the
  1126. X.I test
  1127. Xand performs the command as long as the
  1128. X.I test
  1129. Xis true.
  1130. X.TP
  1131. X.B for (\fIvar\fB in \fIlist\fB) \fIcmd\fB
  1132. X.I rc
  1133. Xsets
  1134. X.I var
  1135. Xto each element of
  1136. X.I list
  1137. X(which may contain variables and backquote substitutions) and runs
  1138. X.IR cmd .
  1139. XIf ``\fBin\fR \fIlist\fR'' is omitted, then
  1140. X.I rc
  1141. Xwill set
  1142. X.I var
  1143. Xto each element of
  1144. X.Cw $*
  1145. X(excluding
  1146. X.Cw $0 .
  1147. XFor example:
  1148. X.Ds
  1149. X.Cw "for (i in `{ls -F | grep '\e*$' | sed 's/\e*$//'}) { commands }
  1150. X.De
  1151. X.PP
  1152. Xwill set
  1153. X.Cw $i
  1154. Xto the name of each file in the current directory which is
  1155. Xexecutable.
  1156. X.SS "Switch"
  1157. X.TP
  1158. X.B switch (\fIlist\fB) { case \fR...\fB }
  1159. X.I rc
  1160. Xlooks inside the braces after a
  1161. X.B switch
  1162. Xstatement for single lines beginning with the word
  1163. X.BR case .
  1164. XIf any of the patterns following
  1165. X.B case
  1166. Xmatch the list supplied to
  1167. X.BR switch ,
  1168. Xthen the commands up until the next
  1169. X.B case
  1170. Xstatement are executed.
  1171. XMetacharacters should not be quoted;
  1172. Xmatching is performed only against the strings in
  1173. X.IR list ,
  1174. Xnot against file names.
  1175. X(Matching for case statements is the same as for the
  1176. X.Cw ~
  1177. Xcommand.)
  1178. X.SS "Logical Operators"
  1179. XThere are a number of operators in
  1180. X.I rc
  1181. Xwhich depend on the exit status of a command.
  1182. X.Ds
  1183. X.Cw "command && command
  1184. X.De
  1185. X.PP
  1186. Xexecutes the first command and then executes the second command if and only if
  1187. Xthe first command exits with a zero exit status (``true'' in UNIX).
  1188. X.Ds
  1189. X.Cw "command || command
  1190. X.De
  1191. X.PP
  1192. Xexecutes the first command executing the second command if and only if
  1193. Xthe second command exits with a nonzero exit status (``false'' in UNIX).
  1194. X.Ds
  1195. X.Cw "! command
  1196. X.De
  1197. X.PP
  1198. Xnegates the exit status of a command.
  1199. XThus:
  1200. X.Ds
  1201. X.Cw "! command || command
  1202. X.De
  1203. X.PP
  1204. Xis equivalent to
  1205. X.Ds
  1206. X.Cw "command && command
  1207. X.De
  1208. X.SH "PATTERN MATCHING"
  1209. XThere are two forms of pattern matching in
  1210. X.IR rc .
  1211. XOne is traditional shell globbing.
  1212. XThis occurs in matching for file names in argument lists:
  1213. X.Ds
  1214. X.Cw "command argument argument ...
  1215. X.De
  1216. X.PP
  1217. XWhen the characters
  1218. X.Cw "*" ,
  1219. X.Cw [
  1220. Xor
  1221. X.Cw ?
  1222. Xoccur in an argument,
  1223. X.I rc
  1224. Xlooks at the
  1225. Xargument as a pattern for matching against files according to the
  1226. Xfollowing rules: a
  1227. X.Cw *
  1228. Xmatches any number (including zero) of
  1229. Xcharacters.
  1230. XA
  1231. X.Cw ?
  1232. Xmatches any single character, and a
  1233. X.Cw [
  1234. Xfollowed by a
  1235. Xnumber of characters followed by a
  1236. X.Cw ]
  1237. Xmatches a single character in that
  1238. Xclass.
  1239. XThe rules for character class matching are the same as those for
  1240. X.IR ed (1),
  1241. Xwith the exception that character class negation is achieved
  1242. Xwith the tilde
  1243. X.Cw ~ ), (
  1244. Xnot the caret
  1245. X.Cw ^ ), (
  1246. Xsince the caret already means
  1247. Xsomething else in
  1248. X.IR rc .
  1249. X.PP
  1250. X.I rc
  1251. Xalso matches patterns against strings with the
  1252. X.Cw ~
  1253. Xcommand:
  1254. X.Ds
  1255. X.Cw "~ subject pattern pattern ...
  1256. X.De
  1257. X.PP
  1258. X.Cw ~
  1259. Xsets
  1260. X.Cw $status
  1261. Xto zero if and only if a supplied pattern matches any
  1262. Xsingle element of the subject list.
  1263. XThus
  1264. X.Ds
  1265. X.Cw "~ foo f*
  1266. X.De
  1267. X.PP
  1268. Xsets status to zero, while
  1269. X.Ds
  1270. X.Cw "~ (bar baz) f*
  1271. X.De
  1272. X.PP
  1273. Xsets status to one.
  1274. XThe null list is matched by the null list, so
  1275. X.Ds
  1276. X.Cw "~ $foo ()
  1277. X.De
  1278. X.PP
  1279. Xchecks to see whether
  1280. X.Cw $foo
  1281. Xis empty or not.
  1282. XThis may also be achieved
  1283. Xby the test
  1284. X.Ds
  1285. X.Cw "~ $#foo 0
  1286. X.De
  1287. X.PP
  1288. XNote that inside a
  1289. X.Cw ~
  1290. Xcommand
  1291. X.I rc
  1292. Xdoes not match patterns against file
  1293. Xnames, so it is not necessary to quote the characters
  1294. X.Cw "*" ,
  1295. X.Cw [
  1296. Xand
  1297. X.Cw "?" .
  1298. XFinally, note that if the
  1299. X.Cw ~
  1300. Xcommand is given a list as its first
  1301. Xargument, then a successful match against any of the elements of that
  1302. Xlist will cause
  1303. X.Cw ~
  1304. Xto return true.
  1305. XFor example:
  1306. X.Ds
  1307. X.Cw "~ (foo goo zoo) z*
  1308. X.De
  1309. X.PP
  1310. Xis true.
  1311. X.SH "LISTS AND VARIABLES"
  1312. XThe primary data structure in
  1313. X.IR rc
  1314. Xis the list, which is a sequence of words.
  1315. XParentheses are used to group lists.
  1316. XThe empty list is represented by
  1317. X.Cw "()" .
  1318. XLists have no hierarchical structure;
  1319. Xa list inside another list is expanded so the
  1320. Xouter list contains all the elements of the inner list.
  1321. XThus, the following are all equivalent
  1322. X.Ds
  1323. X.Cw "one two three
  1324. X
  1325. X.Cw "(one two three)
  1326. X
  1327. X.Cw "((one) () ((two three)))
  1328. X.De
  1329. X.PP
  1330. XNote that the null string,
  1331. X.Cw "''" ,
  1332. Xand the null list,
  1333. X.Cw "()" ,
  1334. Xare two very
  1335. Xdifferent things.
  1336. XAssigning the null string to variable is a valid
  1337. Xoperation, but it does not remove its definition.
  1338. XFor example,
  1339. Xif
  1340. X.Cw $a
  1341. Xis set to
  1342. X.Cw "''" ,
  1343. Xthen
  1344. X.Cw "$#a" ,
  1345. Xreturns a 1.
  1346. X.SS "List Concatenation"
  1347. XTwo lists may be joined by the concatenation operator
  1348. X.Cw ^ ). (
  1349. XA single word is treated as a list of length one, so
  1350. X.Ds
  1351. X.Cw "echo foo^bar
  1352. X.De
  1353. X.PP
  1354. Xproduces the output
  1355. X.Ds
  1356. X.Cw foobar
  1357. X.De
  1358. X.PP
  1359. XFor lists of more than one element,
  1360. Xconcatenation works according to the following rules: if the two lists
  1361. Xhave the same number of elements, then concatenation is pairwise:
  1362. X.Ds
  1363. X.Cw "echo (a\- b\- c\-)^(1 2 3)
  1364. X.De
  1365. X.PP
  1366. Xproduces the output 
  1367. X.Ds
  1368. X.Cw "a\-1 b\-2 c\-3
  1369. X.De
  1370. X.PP
  1371. XOtherwise, one of the lists must have a single element, and then the
  1372. Xconcatenation is distributive:
  1373. X.Ds
  1374. X.Cw "cc \-^(O g c) (malloc alloca)^.c
  1375. X.De
  1376. X.PP
  1377. Xhas the effect of performing the command
  1378. X.Ds
  1379. X.Cw "cc \-O \-g \-c malloc.c alloca.c
  1380. X.De
  1381. X.SS "Free Carets"
  1382. X.I rc
  1383. Xinserts carets (concatenation operators) for free in certain
  1384. Xsituations, in order to save some typing on the user's behalf.
  1385. XFor
  1386. Xexample, the above example could also be typed in as:
  1387. X.Ds
  1388. X.Cw "opts=(O g c) files=(malloc alloca) cc \-$opts $files.c
  1389. X.De
  1390. X.PP
  1391. X.I rc
  1392. Xtakes care to insert a free-caret between the
  1393. X.Cw \- ' `
  1394. Xand
  1395. X.Cw "$opts" ,
  1396. Xas well
  1397. Xas between
  1398. X.Cw $files
  1399. Xand
  1400. X.Cw ".c" .
  1401. XThe rule for free carets is as follows:  if
  1402. Xa word or keyword is immediately
  1403. Xfollowed by another word, keyword, dollar-sign or
  1404. Xbackquote, then
  1405. X.I rc
  1406. Xinserts a caret between them.
  1407. X.SS "Variables"
  1408. XA list may be assigned to a variable, using the notation:
  1409. X.Ds
  1410. X.Cw "var = list
  1411. X.De
  1412. X.PP
  1413. XAny sequence of non-special characters, except a sequence including
  1414. Xonly digits, may be used as a variable name.
  1415. XAll user-defined variables are exported into the environment.
  1416. X.PP
  1417. XThe value of a variable is referenced with the notation:
  1418. X.Ds
  1419. X.Cw $var
  1420. X.De
  1421. X.PP
  1422. XAny variable which has not been assigned a value returns the null list,
  1423. X.Cw "()" ,
  1424. Xwhen referenced. In addition, multiple references are allowed:
  1425. X.Ds
  1426. X.Cw a=foo
  1427. X.Cw b=a
  1428. X.Cw echo $$b
  1429. X.De
  1430. X.PP
  1431. Xprints
  1432. X.Ds
  1433. X.Cw foo
  1434. X.De
  1435. X.PP
  1436. XA variable's definition may also be removed by
  1437. Xassigning the null list to a variable:
  1438. X.Ds
  1439. X.Cw var=()
  1440. X.De
  1441. X.PP
  1442. XFor ``free careting'' to work correctly,
  1443. X.I rc
  1444. Xmust make certain assumptions
  1445. Xabout what characters may appear in a variable name.
  1446. X.I rc
  1447. Xcurrently
  1448. Xassumes that a variable name consists only of alphanumeric characters,
  1449. Xunderscore
  1450. X.Cw _ ) (
  1451. Xand star
  1452. X.Cw * ). (
  1453. XTo reference a variable with other
  1454. Xcharacters in its name, quote the variable name.
  1455. XThus:
  1456. X.Ds
  1457. X.Cw "echo $'we$Ird\Variab!le'
  1458. X.De
  1459. X.SS "Local Variables"
  1460. XAny number of variable assignments may be made local to a single
  1461. Xcommand by typing:
  1462. X.Ds
  1463. X.Cw "a=foo b=bar ... command
  1464. X.De
  1465. X.PP
  1466. XThe command may be a compound command, so for example:
  1467. X.Ds
  1468. X.Cw "path=. ifs=() {
  1469. X.Cw     ...
  1470. X.De
  1471. X.PP
  1472. Xsets path to 
  1473. X.Cw .
  1474. Xand ifs to
  1475. X.Cw ()
  1476. Xfor the duration of one long compound
  1477. Xcommand.
  1478. X.SS "Variable Subscripts"
  1479. XVariables may be subscripted with the notation
  1480. X.Ds
  1481. X\f\*(Cf$var(\fIn\f\*(Cf\fR)
  1482. X.De
  1483. X.PP
  1484. Xwhere
  1485. X.I n
  1486. Xis a list of integers (origin 1).
  1487. XThe list of subscripts need
  1488. Xnot be in order or even unique.
  1489. XThus, if
  1490. X.Ds
  1491. X.Cw "a=(one two three)
  1492. X.De
  1493. X.PP
  1494. Xthen
  1495. X.Ds
  1496. X.Cw "echo $a(3 3 3)
  1497. X.De
  1498. X.PP
  1499. Xprints
  1500. X.Ds
  1501. X.Cw "three three three
  1502. X.De
  1503. X.PP
  1504. XIf
  1505. X.I n
  1506. Xreferences a nonexistent element, then
  1507. X\f\*(Cf$var(\fIn\f\*(Cf\fR)
  1508. Xreturns the null
  1509. Xlist.
  1510. XThe notation
  1511. X.Cw "$\fIn" ,
  1512. Xwhere
  1513. X.I n
  1514. Xis an integer, is a shorthand for
  1515. X\f\*(Cf$*(\fIn\f\*(Cf)\fR.
  1516. XThus,
  1517. X.IR rc 's
  1518. Xarguments may be referred to as
  1519. X.Cw "$1" ,
  1520. X.Cw "$2" ,
  1521. Xand so on.
  1522. X.PP
  1523. XNote also that the list of subscripts may be given by any of
  1524. X.IR rc 's
  1525. Xlist operations:
  1526. X.Ds
  1527. X.Cw "$var(`{awk 'BEGIN{for(i=1;i<=10;i++)print i;exit; }'})
  1528. X.De
  1529. X.PP
  1530. Xreturns the first 10 elements of
  1531. X.Cw $var .
  1532. X.PP
  1533. XTo count the number of elements in a variable, use
  1534. X.Ds
  1535. X.Cw $#var
  1536. X.De
  1537. X.PP
  1538. XThis returns a single-element list, with the number of elements in
  1539. X.Cw $var .
  1540. X.SS "Flat Lists"
  1541. XIn order to create a single-element list from a multi-element list,
  1542. Xwith the components space-separated, use
  1543. X.Ds
  1544. X.Cw $^var
  1545. X.De
  1546. X.PP
  1547. XThis is useful when the normal list concatenation rules need to be
  1548. Xbypassed.
  1549. XFor example, to append a single period at the end of
  1550. X.Cw $path ,
  1551. Xuse:
  1552. X.Ds
  1553. X.Cw "echo $^path.
  1554. X.De
  1555. X.SS "Backquote Substitution"
  1556. XA list may be formed from the output of a command by using backquote
  1557. Xsubstitution:
  1558. X.Ds
  1559. X.Cw "`{ command }
  1560. X.De
  1561. X.PP
  1562. Xreturns a list formed from the standard output of the command in braces.
  1563. X.Cw $ifs
  1564. Xis used to split the output into list elements.
  1565. XBy default,
  1566. X.Cw $ifs
  1567. Xhas the value space-tab-newline.
  1568. XThe braces may be omitted if the command is a single word.
  1569. XThus
  1570. X.Cw `ls
  1571. Xmay be used instead of
  1572. X.Cw "`{ls}" .
  1573. XThis last feature is useful when defining functions that expand
  1574. Xto useful argument lists. A frequent use is:
  1575. X.Ds
  1576. X.Cw "fn src { echo *.[chy] }
  1577. X.De
  1578. X.PP
  1579. Xfollowed by
  1580. X.Ds
  1581. X.Cw "wc `src
  1582. X.De
  1583. X.PP
  1584. X(This will print out a word-count of all C source files in the current
  1585. Xdirectory.)
  1586. X.PP
  1587. XIn order to override the value of
  1588. X.Cw $ifs
  1589. Xfor a single backquote
  1590. Xsubstitution, use:
  1591. X.Ds
  1592. X.Cw "`` (ifs-list) { command }
  1593. X.De
  1594. X.PP
  1595. X.Cw $ifs
  1596. Xwill be temporarily ignored and the command's output will be split as specified by
  1597. Xthe list following the double backquote.
  1598. XFor example:
  1599. X.Ds
  1600. X.Cw "`` ($nl :) {cat /etc/passwd}
  1601. X.De
  1602. X.PP
  1603. Xsplits up
  1604. X.I /etc/passwd
  1605. Xinto fields, assuming that
  1606. X.Cw $nl
  1607. Xcontains a newline
  1608. Xas its value.
  1609. X.SH "SPECIAL VARIABLES"
  1610. XSeveral variables are known to
  1611. X.I rc
  1612. Xand are treated specially.
  1613. X.TP
  1614. X.B *
  1615. XThe argument list of
  1616. X.IR rc .
  1617. X.Cw "$1, $2,
  1618. Xetc. are the same as
  1619. X.Cw $*(1) ,
  1620. X.Cw $*(2) ,
  1621. Xetc.
  1622. XThe variable
  1623. X.Cw $0
  1624. Xholds the value of
  1625. X.Cw argv[0]
  1626. Xwith which
  1627. X.I rc
  1628. Xwas invoked.
  1629. XAdditionally,
  1630. X.Cw $0
  1631. Xis set to the name of a function for the duration of
  1632. Xthe execution of that function, and
  1633. X.Cw $0
  1634. Xis also set to the name of the
  1635. Xfile being interpreted for the duration of a 
  1636. X.Cw .
  1637. Xcommand.
  1638. X.TP
  1639. X.B apid
  1640. XThe process ID of the last process started in the background.
  1641. X.TP
  1642. X.B cdpath
  1643. XA list of directories to search for the target of a
  1644. X.B cd
  1645. Xcommand.
  1646. XThe empty string stands for the current directory. Note that
  1647. Xan assignment to
  1648. X.Cw $cdpath
  1649. Xcauses an automatic assignment to
  1650. X.Cw $CDPATH ,
  1651. Xand vice-versa
  1652. X.TP
  1653. X.B history
  1654. X.Cw $history
  1655. Xcontains the name of a file to which commands are appended as
  1656. X.I rc
  1657. Xreads them.
  1658. XThis facilitates the use of a stand-alone history program
  1659. Xwhich parses the contents of the history file and presents them to
  1660. X.I rc
  1661. Xfor reinterpretation.
  1662. XIf
  1663. X.Cw $history
  1664. Xis not set, then
  1665. X.I rc
  1666. Xdoes not append commands to any file.
  1667. X.TP
  1668. X.B home
  1669. XThe default directory for the builtin cd command and is the directory
  1670. Xin which
  1671. X.I rc
  1672. Xlooks to find its initialization file,
  1673. X.IR .rcrc ,
  1674. Xif
  1675. X.I rc
  1676. Xhas been started up as a login shell. Like
  1677. X.Cw $cdpath
  1678. Xand
  1679. X.Cw $CDPATH ,
  1680. X.Cw $home
  1681. Xand
  1682. X.Cw $HOME
  1683. Xare aliased to each other.
  1684. X.TP
  1685. X.B ifs
  1686. XThe internal field separator, used for splitting up the output of
  1687. Xbackquote commands for digestion as a list.
  1688. X.TP
  1689. X.B path
  1690. XThis is a list of directories to search in for commands.
  1691. XThe empty string stands for the current directory. Note that
  1692. Xlike
  1693. X.Cw $cdpath
  1694. Xand
  1695. X.Cw $CDPATH ,
  1696. X.Cw $path
  1697. Xand
  1698. X.Cw $PATH
  1699. Xare aliased to each other.
  1700. X.TP
  1701. X.B pid
  1702. XThe process ID of the currently running
  1703. X.IR rc .
  1704. X.TP
  1705. X.B prompt
  1706. XThis variable holds the two prompts (in list form, of course) that
  1707. X.I rc
  1708. Xprints.
  1709. X.Cw $prompt(1)
  1710. Xis printed before each command is read, and
  1711. X.Cw $prompt(2)
  1712. Xis printed when input is expected to continue on the next
  1713. Xline.
  1714. X.I rc
  1715. Xsets
  1716. X.Cw $prompt
  1717. Xto
  1718. X.Cw "('; ' '')
  1719. Xby default.
  1720. XThe reason for this is that it enables an
  1721. X.I rc
  1722. Xuser to grab commands from previous lines using a
  1723. Xmouse, and to present them to
  1724. X.I rc
  1725. Xfor re-interpretation; the semicolon
  1726. Xprompt is simply ignored by
  1727. X.IR rc .
  1728. XThe null
  1729. X.Cw $prompt(2)
  1730. Xalso has its
  1731. Xjustification:  an
  1732. X.I rc
  1733. Xscript, when typed interactively, will not leave 
  1734. X.Cw $prompt(2) 's
  1735. Xon the screen,
  1736. Xand can therefore be grabbed by a mouse and placed
  1737. Xdirectly into a file for use as a shell script, without further editing
  1738. Xbeing necessary.
  1739. X.TP
  1740. X.B prompt (function)
  1741. XIf this function is set, then it gets executed every time
  1742. X.I rc
  1743. Xis about to print
  1744. X.Cw "$prompt(1)" .
  1745. X.TP
  1746. X.B status
  1747. XThe exit status of the last command.
  1748. XIf the command exited with a numeric value,
  1749. Xthat number is the status.
  1750. XIf the died with a signal,
  1751. Xthe status is the name of that signal; if a core file
  1752. Xwas created, the string
  1753. X.Cw +core '' ``
  1754. Xis appended.
  1755. XThe value of
  1756. X.Cw $status
  1757. Xfor a pipeline is a list, with one entry,
  1758. Xas above, for each process in the pipeline.
  1759. XFor example, the command 
  1760. X.Ds 1i
  1761. X.Cw "ls | wc
  1762. X.De
  1763. X.TP
  1764. X\&
  1765. Xusually sets
  1766. X.Cw $status
  1767. Xto
  1768. X.Cw "(0 0)" .
  1769. X.PP
  1770. XThe values of
  1771. X.Cw "$path" ,
  1772. X.Cw "$cdpath" ,
  1773. Xand
  1774. X.Cw $home
  1775. Xare derived from the environment
  1776. Xvalues of
  1777. X.Cw "$PATH" ,
  1778. X.Cw "$CDPATH" ,
  1779. Xand
  1780. X.Cw "$HOME" .
  1781. XOtherwise, they are derived from
  1782. Xthe environment values of
  1783. X.Cw $path ,
  1784. X.Cw $cdpath
  1785. Xand
  1786. X.Cw $home .
  1787. XThis is for compatibility with other UNIX programs, like
  1788. X.IR sh (1).
  1789. X.Cw $PATH
  1790. Xand
  1791. X.Cw $CDPATH
  1792. Xare assumed to be colon-separated lists.
  1793. X.SH FUNCTIONS
  1794. X.I rc
  1795. Xfunctions are identical to
  1796. X.I rc
  1797. Xscripts, except that they are stored
  1798. Xin memory and are automatically exported into the environment.
  1799. XA shell function is declared as:
  1800. X.Ds
  1801. X.Cw "fn name { commands }
  1802. X.De
  1803. X.PP
  1804. X.I rc
  1805. Xscans the definition in until the close-brace, so the function can
  1806. Xspan more than one line.
  1807. XThe function definition may be removed by typing
  1808. X.Ds
  1809. X.Cw "fn name
  1810. X.De
  1811. X.PP
  1812. XWhen a function is executed,
  1813. X.Cw $*
  1814. Xis set to the arguments to that
  1815. Xfunction for the duration of the command.
  1816. XThus a reasonable definition for
  1817. X.Cw "l" ,
  1818. Xa shorthand for
  1819. X.IR ls (1),
  1820. Xcould be:
  1821. X.Ds
  1822. X.Cw "fn l { ls -FC $* }
  1823. X.De
  1824. X.PP
  1825. Xbut not
  1826. X.Ds
  1827. X.Cw "fn l { ls -FC }
  1828. X.De
  1829. X.SH "INTERRUPTS AND SIGNALS"
  1830. X.I rc
  1831. Xrecognizes a number of signals, and allows the user to define shell
  1832. Xfunctions which act as signal handlers.
  1833. X.I rc
  1834. Xby default traps
  1835. X.Cw SIGINT
  1836. Xand
  1837. X.Cw SIGQUIT
  1838. Xwhen it is interactive mode.
  1839. X.Cw SIGQUIT
  1840. Xis ignored, unless
  1841. X.I rc
  1842. Xhas been invoked with the 
  1843. X.Cw \-d
  1844. Xflag.
  1845. XHowever, user-defined signal handlers may be written for these and
  1846. Xall other signals.
  1847. XThe way to define a signal handler is to
  1848. Xwrite a function by the name of the signal in lower case.
  1849. XThus:
  1850. X.Ds
  1851. X.Cw "fn sighup { echo hangup; rm /tmp/rc$pid.*; exit }
  1852. X.De
  1853. X.PP
  1854. XIn addition to Unix signals, rc recognizes the artificial signal
  1855. X.Cw SIGEXIT
  1856. Xwhich occurs as rc is about to exit.
  1857. X.PP
  1858. XIn order to remove a signal handler's definition, remove it as though
  1859. Xit were a regular function.
  1860. XFor example:
  1861. X.Ds
  1862. X.Cw "fn sigint
  1863. X.De
  1864. X.PP
  1865. Xreturns the handler of
  1866. X.Cw SIGINT
  1867. Xto the default value.
  1868. XIn order to ignore a signal, set the signal handler's value to
  1869. X.Cw "{}" .
  1870. XThus:
  1871. X.Ds
  1872. X.Cw "fn sigint {}
  1873. X.De
  1874. X.PP
  1875. Xcauses SIGINT to be ignored by the shell.
  1876. X.SH "BUILTIN COMMANDS"
  1877. XBuiltin commands execute in the context of the shell, but otherwise
  1878. Xbehave exactly like other commands.
  1879. X.TP
  1880. X.B .  \fR[\fB\-i\fR]\fB \fIfile args\fB
  1881. XReads \fIfile\fP as input to
  1882. X.IR rc
  1883. Xand executes its contents.
  1884. XWith a
  1885. X.Cw \-i
  1886. Xflag, input is interactive.
  1887. XThus
  1888. Xfrom within a shell script, 
  1889. X.Ds 1i
  1890. X.Cw ". \-i /dev/tty
  1891. X.De
  1892. X.TP
  1893. X\&
  1894. Xdoes the ``right'' thing.
  1895. X.TP
  1896. X.B break
  1897. XBreaks from the innermost
  1898. X.B for
  1899. Xor
  1900. X.BR while ,
  1901. Xas in C.
  1902. XIt is an error to
  1903. Xinvoke
  1904. X.B break
  1905. Xoutside of a loop.
  1906. X(Note that
  1907. Xthere is no
  1908. X.B break
  1909. Xkeyword between
  1910. Xcommands in
  1911. X.B switch
  1912. Xstatements, unlike C.)
  1913. X.TP
  1914. X.B builtin \fIcommand ...\fB
  1915. XExecutes the command as a builtin; no function lookup or directory
  1916. Xsearching is done.
  1917. XThis command is present to allow functions with the
  1918. Xsame names as builtins to use the underlying builtin.
  1919. X.TP
  1920. X.B cd \fIdirectory\fB
  1921. XChange the current directory.
  1922. XThe variable
  1923. X.Cw $cdpath
  1924. Xis searched for
  1925. Xpossible locations of \fIdirectory\fP, analogous to the searching of
  1926. X.Cw $path
  1927. Xfor executable files.
  1928. XWith no argument,
  1929. X.B cd
  1930. Xchanges directory to
  1931. X.Cw "$home" .
  1932. X.TP
  1933. X.B echo \fIargs ...\fB
  1934. XPrints its arguments to standard output.
  1935. XArguments are separated by spaces.
  1936. XIf the first argument is
  1937. X.Cw "\-n" ,
  1938. Xno final newline is printed.
  1939. XIf the first argument is
  1940. X.Cw "\-\-" ,
  1941. Xthen any subsequent arguments are ignored.
  1942. X.TP
  1943. X.B eval \fIlist\fB
  1944. X.B eval
  1945. Xconcatenates the elements of
  1946. X.I list
  1947. Xwith spaces and feeds the resulting string to
  1948. X.I rc
  1949. Xfor re-scanning.
  1950. XThis is the only time input is rescanned in
  1951. X.IR rc .
  1952. X.TP
  1953. X.B exec \fIcommand\fB
  1954. Xreplaces
  1955. X.I rc
  1956. Xwith the given command.
  1957. XIf the exec contains only redirections,
  1958. Xthen these redirections apply to the current shell
  1959. Xand the shell does not exit.
  1960. XFor example,
  1961. X.Ds 1i
  1962. X.Cw "exec >[2] err.out
  1963. X.De
  1964. X.TP
  1965. X\&
  1966. Xplaces further output to standard error in the file
  1967. X.IR err.out .
  1968. X.TP
  1969. X.B exit \fIstatus\fB
  1970. XCause the current shell to exit with the given exit
  1971. X.IR status .
  1972. XIf no argument is given, the current value of
  1973. X.Cw $status
  1974. Xis used.
  1975. X.TP
  1976. X.B limit \fR[\fB\-h\fR]\fB \fR[\fIresource\fR]\fB \fR[\fIvalue\fR]\fB
  1977. XSimilar to the
  1978. X.IR csh (1)
  1979. Xlimit builtin, this command operates upon the
  1980. XBSD-style limits of a process.
  1981. XThe
  1982. X.Cw \-h
  1983. Xflag displays/alters the hard
  1984. Xlimits.
  1985. XThe resources which can be shown or altered are
  1986. X.BR cputime ,
  1987. X.BR filesize ,
  1988. X.BR datasize ,
  1989. X.BR stacksize ,
  1990. X.B coredumpsize
  1991. Xand
  1992. X.BR memoryuse .
  1993. XFor
  1994. Xexample:
  1995. X.Ds 1i
  1996. X.Cw "limit coredumpsize 0
  1997. X.De
  1998. X.TP
  1999. X\&
  2000. Xdisables core dumps.
  2001. X.TP
  2002. X.B return \fIn\fB
  2003. XReturns from the current function, with status
  2004. X.IR n .
  2005. XIf
  2006. X.IR n
  2007. Xis omitted, then
  2008. X.Cw $status
  2009. Xis left unchanged.
  2010. XIt is an error to invoke
  2011. X.B return
  2012. Xwhen not inside a function.
  2013. X.TP
  2014. X.B shift \fIn\fB
  2015. XDeletes
  2016. X.I n
  2017. Xelements from the beginning of
  2018. X.Cw $*
  2019. Xand shifts the other
  2020. Xelements down by
  2021. X.IR n .
  2022. X.I n
  2023. Xdefaults to 1.
  2024. X(Note that
  2025. X.Cw $0
  2026. Xis not affected by
  2027. X.BR shift .)
  2028. X.TP
  2029. X.B umask \fImask\fB
  2030. XSets the current umask (see
  2031. X.IR umask (2))
  2032. Xto the octal
  2033. X.IR mask .
  2034. XIf no argument is present, the current mask value is printed.
  2035. X.TP
  2036. X.B wait \fIpid\fB
  2037. XWaits for the specified
  2038. X.IR pid ,
  2039. Xwhich must have been started by
  2040. X.IR rc .
  2041. XIf no
  2042. X.I pid
  2043. Xis specified,
  2044. X.I rc
  2045. Xwaits for any child process to exit.
  2046. X.TP
  2047. X.B whatis \fIname ...\fB
  2048. XPrints a definition of the named objects.
  2049. XFor variables, their values
  2050. Xare printed; for functions, their definitions are; and for executable
  2051. Xfiles, path names are printed.
  2052. XWithout arguments,
  2053. X.B whatis
  2054. Xprints the values of all shell variables and functions. Note that
  2055. X.B whatis
  2056. Xoutput is suitable for input to
  2057. X.IR rc ;
  2058. Xby saving the output of
  2059. X.B whatis
  2060. Xin a file, it should be possible to recreate the state of
  2061. X.I rc
  2062. Xby sourcing this file with a
  2063. X.Cw .
  2064. Xcommand.
  2065. X.SH GRAMMAR
  2066. XHere is
  2067. X.IR rc 's
  2068. Xgrammar, edited to remove semantic actions.
  2069. X.Ds
  2070. X\f\*(Cf
  2071. X%term BANG DUP ELSE END FN FOR HUH IF IN LBRACK PIPE RBRACK
  2072. X%term REDIR STAR SUB SUBSHELL SWITCH TWIDDLE WHILE WORD
  2073. X
  2074. X%left IF WHILE FOR SWITCH ')' ELSE
  2075. X%left ANDAND OROR
  2076. X%left BANG SUBSHELL
  2077. X%left PIPE
  2078. X%left '^'
  2079. X%right '$' COUNT FLAT
  2080. X%left SUB
  2081. X%left '`' BACKBACK
  2082. X
  2083. X%%
  2084. X
  2085. Xrc: line end | error end
  2086. X
  2087. Xend: '\en' | END
  2088. X
  2089. Xcmdsa: cmd ';' | cmd '&'
  2090. X
  2091. Xline: cmd | cmdsa line
  2092. X
  2093. Xbody: cmd | cmdsan body
  2094. X
  2095. Xcmdsan: cmdsa | cmd '\en'
  2096. X
  2097. Xbrace: '{' body '}'
  2098. X
  2099. Xparen: '(' body ')'
  2100. X
  2101. Xassign: first '=' word
  2102. X
  2103. Xepilog: /* empty */ | redir epilog
  2104. X
  2105. Xredir: DUP | REDIR word
  2106. X
  2107. Xiftail: cmd %prec IF | brace ELSE cmd
  2108. X
  2109. Xcmd    : /* empty */
  2110. X    | simple
  2111. X    | brace epilog
  2112. X    | IF paren { skipnl(); } iftail
  2113. X    | FOR '(' word IN words ')' { skipnl(); } cmd
  2114. X    | FOR '(' word ')' { skipnl(); } cmd
  2115. X    | WHILE paren { skipnl(); } cmd
  2116. X    | SWITCH '(' word ')' { skipnl(); } brace
  2117. X    | TWIDDLE word words
  2118. X    | cmd ANDAND { skipnl(); } cmd
  2119. X    | cmd OROR { skipnl(); } cmd
  2120. X     | cmd PIPE { skipnl(); } cmd
  2121. X    | redir cmd %prec BANG
  2122. X    | assign cmd %prec BANG
  2123. X    | BANG cmd
  2124. X    | SUBSHELL cmd
  2125. X    | FN words brace
  2126. X    | FN words
  2127. X
  2128. Xsimple: first | simple word | simple redir
  2129. X
  2130. Xfirst: comword | first '^' word
  2131. X
  2132. Xword: comword | keyword | word '^' word
  2133. X
  2134. Xcomword: WORD
  2135. X    | COUNT word | FLAT word
  2136. X    | '`' word | '`' brace
  2137. X    | BACKBACK word brace | BACKBACK word word
  2138. X    | '(' words ')'
  2139. X    | REDIR brace
  2140. X    |  '$' word | '$' word SUB words ')'
  2141. X
  2142. Xkeyword: FOR | IN | WHILE | IF | SWITCH
  2143. X    | FN | ELSE | TWIDDLE | BANG | SUBSHELL
  2144. X
  2145. Xwords: /* empty */ | words word
  2146. X\fR
  2147. X.De
  2148. X.SH FILES
  2149. X.I "$HOME/.rcrc, /tmp/rc*, /dev/null
  2150. X.SH CREDITS
  2151. X.I rc
  2152. Xwas written by Byron Rakitzis, with valuable help
  2153. Xfrom Paul Haahr, Hugh Redelmeier and David Sanderson.
  2154. XThe design of this shell has been copied from the rc
  2155. Xthat Tom Duff wrote at Bell Labs.
  2156. X.SH BUGS
  2157. X.Cw <{foo}
  2158. Xstyle redirection is implemented with named pipes, and it is sometimes
  2159. Xpossible to foil rc into removing the FIFO it places in
  2160. X.I /tmp 
  2161. Xprematurely, or it is even possible to cause rc to hang. This redirection
  2162. Xshould be implemented via
  2163. X.I /dev/fd
  2164. Xon systems which have it.
  2165. X.B
  2166. XThe functionality of
  2167. X.B shift
  2168. Xshould be available for variables other than 
  2169. X.Cw "$*" .
  2170. X.PP
  2171. X.B echo
  2172. Xis built in only for performance reasons, which is a bad idea.
  2173. X.PP
  2174. XThere should be a way to avoid exporting a variable.
  2175. X.PP
  2176. XThe
  2177. X.Cw $^var
  2178. Xnotation for flattening should allow for using an arbitrary
  2179. Xseparating character, not just space.
  2180. X.PP
  2181. XBug reports should be mailed to
  2182. X.Cw "byron@archone.tamu.edu" .
  2183. X.SH INCOMPATIBILITIES
  2184. XHere is a list of features which distinguish this incarnation of
  2185. X.I rc
  2186. Xfrom the one described in the Bell Labs manual pages:
  2187. X.PP
  2188. XThe treatment of if-else is different in the v10
  2189. X.IR rc :
  2190. Xthat version uses
  2191. Xan ``if not'' clause which gets executed if the preceding ``if'' test
  2192. Xdoes not succeed.
  2193. X.PP
  2194. XBackquotes are slightly different in v10
  2195. X.IR rc :
  2196. Xa backquote must always be followed by
  2197. Xa left-brace.
  2198. XThis restriction is not present for single-word
  2199. Xcommands in this
  2200. X.IR rc .
  2201. X.PP
  2202. XThe following are all new with this version of
  2203. X.IR rc :
  2204. XThe list flattening operator,
  2205. Xhere strings (they facilitate exporting of functions
  2206. Xwith here documents into the environment),
  2207. Xthe
  2208. X.B return
  2209. Xand
  2210. X.B break
  2211. Xkeywords,
  2212. Xthe
  2213. X.B echo
  2214. Xbuiltin,
  2215. Xthe support for the GNU
  2216. X.IR readline (3)
  2217. Xlibrary and
  2218. Xthe support for the
  2219. X.B prompt
  2220. Xfunction.
  2221. XThis
  2222. X.I rc
  2223. Xalso sets
  2224. X.Cw $0
  2225. Xto the name of a function being executed/file
  2226. Xbeing sourced.
  2227. X.SH "SEE ALSO"
  2228. X``rc \(em A shell for Plan 9 and UNIX'',
  2229. XUnix Research System,
  2230. X10th Edition,
  2231. Xvol. 2. (Saunders College Publishing)
  2232. END_OF_FILE
  2233.   if test 30362 -ne `wc -c <'rc.1'`; then
  2234.     echo shar: \"'rc.1'\" unpacked with wrong size!
  2235.   fi
  2236.   # end of 'rc.1'
  2237. fi
  2238. echo shar: End of archive 1 \(of 4\).
  2239. cp /dev/null ark1isdone
  2240. MISSING=""
  2241. for I in 1 2 3 4 ; do
  2242.     if test ! -f ark${I}isdone ; then
  2243.     MISSING="${MISSING} ${I}"
  2244.     fi
  2245. done
  2246. if test "${MISSING}" = "" ; then
  2247.     echo You have unpacked all 4 archives.
  2248.     rm -f ark[1-9]isdone
  2249. else
  2250.     echo You still must unpack the following archives:
  2251.     echo "        " ${MISSING}
  2252. fi
  2253. exit 0
  2254. exit 0 # Just in case...
  2255. -- 
  2256. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  2257. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  2258. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  2259. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  2260.